package models

import (
	"errmsg"
	"errors"
	"github.com/astaxie/beego"
	"github.com/astaxie/beego/logs"
	"github.com/astaxie/beego/orm"
	"time"
	"tools"
)

type UseMode struct {
	Id         string          `orm:"column(id);pk" json:"id" form:"id"`
	UserId     string          `orm:"column(user_id)" json:"user_id" form:"user_id"`
	Name       string          `orm:"column(name)" json:"name" form:"name"`
	Trigger    int             `orm:"column(trigger)" json:"trigger" form:"trigger"`
	IsActivate int             `orm:"column(is_activate)" json:"is_activate" form:"is_activate"`
	StartTime  string          `orm:"column(start_time)" json:"start_time" form:"start_time"`
	EndTime    string          `orm:"column(end_time)" json:"end_time" form:"end_time"`
	IsPush     int             `orm:"column(is_push)" json:"is_push" form:"is_push"`
	Wkocc      string          `orm:"column(wkocc)" json:"wkocc" form:"wkocc"`
	IsShare    int             `orm:"column(is_share)" json:"is_share" form:"is_share"`
	IsOriginal int             `orm:"column(is_original)" json:"is_original" form:"is_original"`
	CreateTime int64           `orm:"column(create_time)" json:"create_time" form:"create_time"`
	Sort       int             `orm:"column(sort)" json:"sort" form:"sort"`
	MarketId   int             `orm:"column(market_id)" json:"market_id" form:"market_id"`
	Task       []*UseModeTasks `orm:"-" json:"task"`
}

const (
	UM_MANUAL = 1 // 手动
	UM_TIMING = 2 // 定时
)

func init() {
	orm.RegisterModel(new(UseMode))
}

func (m *UseMode) TableName() string {
	return "use_mode"
}

func NewUseMode() *UseMode {
	return &UseMode{}
}

func GetAllUseModeByUid(uid string, page int) ([]*UseMode, error) {
	var (
		err error
		ls  []*UseMode
		qs  orm.QuerySeter
	)

	qs = orm.NewOrm().QueryTable(NewUseMode().TableName()).Filter("user_id", uid).OrderBy("-create_time")
	if page > 0 {
		row := beego.AppConfig.DefaultInt("page_limit", 20)
		start := (page - 1) * row
		qs = qs.Limit(row).Offset(start)
	}
	if _, err = qs.All(&ls); err != nil {
		logs.Error("GetAllUseModeByUid error:", err)
		return nil, errmsg.ErrResponseSystem
	}

	if len(ls) == 0 {
		return nil, nil
	}

	for k, v := range ls {
		ls[k].Task, _ = GetUseModeTaskByUmid(v.Id, v.UserId)
	}

	return ls, nil
}

func GetUseModeById(id string) (*UseMode, error) {
	var (
		err error
		um  *UseMode
	)
	um = &UseMode{Id: id}
	err = orm.NewOrm().Read(um)
	if err == orm.ErrNoRows {
		return nil, nil
	}
	if err != nil {
		logs.Error("GetUseModeById error:", err)
		return nil, err
	}
	um.Task, _ = GetUseModeTaskByUmid(um.Id, um.UserId)
	return um, nil
}

func IsExistsUseModeByName(uid, name string, id ...string) (bool, error) {
	var (
		count int
		vals  []interface{}
	)
	sql := `SELECT count(id) FROM use_mode WHERE user_id = ? AND name = ?`
	vals = append(vals, uid, name)
	if len(id) > 0 {
		sql += " and id != ?"
		vals = append(vals, id[0])
	}
	if err := orm.NewOrm().Raw(sql).SetArgs(vals).QueryRow(&count); err != nil {
		logs.Error(err)
		return false, err
	}
	if count == 0 {
		return false, nil
	}
	return true, nil
}

func GetUseModeByName(uid, name string, suffix ...string) (*UseMode, error) {
	var (
		um  = &UseMode{}
		err error
	)

	if len(suffix) == 0 {
		err = orm.NewOrm().Raw(`SELECT * FROM use_mode WHERE user_id = ? AND name = ?`, uid, name).QueryRow(um)
	} else {
		err = orm.NewOrm().Raw(`SELECT * FROM use_mode WHERE user_id = ? AND (name = ? or name = ?)`, uid, name, name+suffix[0]).QueryRow(um)
	}
	if err == orm.ErrNoRows {
		return nil, nil
	}
	if err != nil {
		logs.Error("GetUseModeByName error:", err)
		return nil, errmsg.ErrResponseSystem
	}
	return um, nil
}

// 添加使用模式
func AddUseMode(um *UseMode) error {
	var (
		o   orm.Ormer
		err error
		num int64
		is  bool
	)

	if is, err = IsExistsUseModeByName(um.UserId, um.Name); err != nil {
		return err
	}
	if is {
		return errors.New("模式名称重复")
	}

	if len(um.Id) == 0 {
		um.Id = tools.GUUID()
	}
	um.CreateTime = time.Now().Unix()
	um.IsActivate = 1

	o = orm.NewOrm()
	o.Begin()
	if _, err = o.Insert(um); err != nil {
		o.Rollback()
		logs.Error("AddUseMode error:", err)
		return errmsg.ErrResponseSystem
	}

	for k, _ := range um.Task {
		um.Task[k].Id = tools.GUUID()
		um.Task[k].UseModeId = um.Id
		um.Task[k].Order = k
	}

	num, err = o.InsertMulti(len(um.Task), um.Task)
	if err != nil {
		o.Rollback()
		logs.Error("AddUseMode error:", err)
		return errmsg.ErrResponseSystem
	}

	if int(num) != len(um.Task) {
		o.Rollback()
		logs.Error(err)
		return errmsg.ErrResponseFail
	}

	o.Commit()
	return nil
}

func UpdateUseMode(um *UseMode) error {
	var (
		o   orm.Ormer
		err error
		num int64
		is  bool
	)

	if is, err = IsExistsUseModeByName(um.UserId, um.Name, um.Id); err != nil {
		return err
	}
	if is {
		return errors.New("模式名称重复")
	}

	o = orm.NewOrm()
	o.Begin()

	if _, err = orm.NewOrm().QueryTable(NewUseModeTasks().TableName()).Filter("use_mode_id", um.Id).Delete(); err != nil {
		logs.Error("UpdateUseMode error:", err)
		o.Rollback()
		return errmsg.ErrResponseSystem
	}

	if _, err = o.Update(um); err != nil {
		o.Rollback()
		logs.Error("UpdateUseMode error:", err)
		return errmsg.ErrResponseSystem
	}

	for k, _ := range um.Task {
		um.Task[k].Id = tools.GUUID()
		um.Task[k].UseModeId = um.Id
		um.Task[k].Order = k
	}

	num, err = o.InsertMulti(len(um.Task), um.Task)
	if err != nil {
		o.Rollback()
		logs.Error("UpdateUseMode error:", err)
		return errmsg.ErrResponseSystem
	}

	if int(num) != len(um.Task) {
		o.Rollback()
		logs.Error(err)
		return errmsg.ErrResponseFail
	}

	o.Commit()
	return nil
}

// 根据使用模式id删除任务
func DelUseModeById(id string) error {
	var (
		o   orm.Ormer
		err error
		sql string
	)
	o = orm.NewOrm()
	if err = o.Begin(); err != nil {
		return err
	}

	// 删除使用模式
	sql = "DELETE FROM use_mode WHERE id = ?"
	if _, err = o.Raw(sql).SetArgs(id).Exec(); err != nil {
		o.Rollback()
		logs.Error("DelUseModeById error:", err)
		return errmsg.ErrResponseSystem
	}

	// 删除任务列表
	sql = "DELETE FROM use_mode_tasks WHERE use_mode_id = ?"
	if _, err = o.Raw(sql).SetArgs(id).Exec(); err != nil {
		o.Rollback()
		logs.Error("DelUseModeById error:", err)
		return errmsg.ErrResponseSystem
	}

	err = o.Commit()
	return nil
}

func UpdateUseModeStatus(um *UseMode) error {
	// 数据入库
	if _, err := orm.NewOrm().Update(um); err != nil {
		logs.Error("UpdateUseModeStatus error:", err)
		return errmsg.ErrResponseSystem
	}
	return nil
}
